import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { CreateDailyDto } from './dto/create-daily.dto';
import { UpdateDailyDto } from './dto/update-daily.dto';
import { Daily } from './entities/daily.entity';
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import {
  EntityManager,
  FindOptionsWhere,
  In,
  IsNull,
  Not,
  Repository,
} from 'typeorm';
import { LikeService } from 'src/like/like.service';
import { Like } from 'src/like/entities/like.entity';
import { Comment } from 'src/comment/entities/comment.entity';
import { UploadService } from 'src/upload/upload.service';
import { filterSensitiveWords } from 'src/utils';

@Injectable()
export class DailyService {
  @InjectEntityManager()
  private manage: EntityManager;

  @InjectRepository(Daily)
  private dailyRepository: Repository<Daily>;

  @InjectRepository(Comment)
  private commentRepository: Repository<Comment>;
  @Inject(LikeService)
  private likeService: LikeService;

  @Inject(UploadService)
  private uploadService: UploadService;

  async create(createDailyDto: CreateDailyDto) {
    const {userId, content, ip, avatar, authorName, images} = createDailyDto
    const filterContent:string = filterSensitiveWords(content)
    const daily = new Daily();
    daily.userId = userId;
    daily.content = filterContent;
    daily.ip = ip;
    daily.avatar = avatar;
    daily.authorName = authorName;
    images ? (daily.images = images) : '';
    try {
      return await this.manage.save(Daily, daily);
    } catch (error) {
      new HttpException(error, HttpStatus.BAD_REQUEST);
    }
  }

  async findAll(userId: number) {
    // 查说说点赞汇总
    let likeList = [];
    if (userId) {
      likeList = await this.likeService.findLikeByUserIdAndType(userId, 2);
    }
    const daily = await this.manage.find(Daily);

    return daily.map((i) => {
      if (likeList.some((like) => like.createId === i.id)) {
        i.action = 1;
      }
      return i;
    });
  }

  // 点赞说说
  async like(createId: number) {
    try {
      return await this.manage.increment(Daily, { id: createId }, 'like', 1);
    } catch (error) {
      new HttpException(error, HttpStatus.BAD_REQUEST);
    }
  }

  // 取消点赞
  async unlike(createId: number) {
    try {
      return await this.manage.decrement(Daily, { id: createId }, 'like', 1);
    } catch (error) {
      new HttpException(error, HttpStatus.BAD_REQUEST);
    }
  }

  // comment
  async commentIncrement(createId: number) {
    return await this.manage.increment(
      Daily,
      { id: createId },
      'comment_times',
      1,
    );
  }

  // delete comment
  async commentDecrement(createId: number) {
    return await this.manage.decrement(
      Daily,
      { id: createId },
      'comment_times',
      1,
    );
  }

  findOne(id: number) {
    return `This action returns a #${id} daily`;
  }

  update(id: number, updateDailyDto: UpdateDailyDto) {
    return `This action updates a #${id} daily`;
  }

  async remove(id: number) {
    const _Type = 2; //说说的业务类型为2
    // 开启事务
    /**
     * @流程1 说说--->说说点赞--->说说图片@oss --->说图片@upload
     * @流程2 (说说评论--->说说评论图片@oss ---> 说说评论图片@upload --->评论点赞)
     */
    const queryRunner =
      this.dailyRepository.manager.connection.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();
    try {
      const daily = await this.manage.findOneBy(Daily, { id: id });
      const whereOptions: FindOptionsWhere<Comment> = {
        // name: In(nameValues),
        createId: id,
        type: _Type, //说说的业务类型为2
        commentPic: Not(IsNull()),
      };
      const commentPics = await queryRunner.manager.find(Comment, {
        where: whereOptions,
        select: ['commentPic'],
      });

      // 评论里面有点赞的
      const commentLikeIds = await queryRunner.manager
        .createQueryBuilder(Comment, 'c')
        .select('c.id')
        .where('c.createId = :createId', { createId: id })
        .andWhere('c.type = :type', { type: 2 }) //说说的业务类型为2
        .andWhere('c.like > :condition', { condition: 0 })
        .getMany();

      if (commentLikeIds?.length) {
        //删除评论的点赞
        await queryRunner.manager
          .createQueryBuilder()
          .delete()
          .from(Like)
          .where('createId IN (:...createIds)', {
            createIds: commentLikeIds.map((i) => i.id),
          })
          .andWhere('type = :type', { type: 3 }) //评论的业务类型3
          .execute();
      }
      // 删除评论
      await queryRunner.manager
        .createQueryBuilder()
        .delete()
        .from(Comment)
        .where('createId = :createId', { createId: id })
        .andWhere('type = :type', { type: _Type })
        .execute();
      // 删除说说点赞
      await queryRunner.manager
        .createQueryBuilder()
        .delete()
        .from(Like)
        .where('createId = :createId', { createId: id })
        .andWhere('type = :type', { type: _Type })
        .execute();
      const res = await queryRunner.manager.delete(Daily, { id });
      if (res?.affected == 1) {
        let imageUrls = '';
        daily?.images?.length ? (imageUrls += daily.images) : '';
        if (commentPics?.length) {
          imageUrls += ',' + commentPics.map((i) => i.commentPic).join(',');
        }
        if (imageUrls) {
          const urlRes = await this.uploadService.multiDelete(imageUrls);
          console.log('OSS删除成功的图片url', urlRes);
          await this.uploadService.deleteImageUrl(imageUrls)
        }
      } else {
        await queryRunner.rollbackTransaction()
        throw new HttpException('删除出错了', HttpStatus.BAD_REQUEST)
      }
      await queryRunner.commitTransaction();
      return res;
    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw new HttpException('出错回滚', HttpStatus.BAD_REQUEST);
    } finally {
      await queryRunner.release();
    }
  }
}
